package com.bb.blog.code.spring;

import com.bb.blog.code.mybatis.StartConfiguration;
import com.bb.blog.code.mybatis.example.Dog;
import com.bb.blog.code.mybatis.mapper.MapperXScan;
import com.bb.blog.code.spring.aop.AopConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.*;


public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
                Test.class, Config1.class, Config2.class,Config3.class
        );

        Dog dog = context.getBean(Dog.class);
        dog.bark();
        Test2 test2 = context.getBean(Test2.class);
        test2.sout();


        Cat cat = context.getBean(Cat.class);
        Config3 config3 = context.getBean(Config3.class);
        config3.sout();
    }

    public Test() {
        System.out.println("Test was init");
    }

    @Configuration
    @MapperXScan(scanPackages = "com.bb.blog.code.mybatis.example")
    @Import(StartConfiguration.class)
    public static class Config1 {

    }

    @Configuration
    @EnableAspectJAutoProxy
    @Import(AopConfig.class)
    public static class Config2 implements BeanFactoryAware {
        private final Logger logger = LoggerFactory.getLogger(Config2.class);
        BeanFactory beanFactory;

        public Config2(){
            System.out.println("12345");
        }
        @Bean
        Test2 test2() {
            return new Test2();
        }
//        @Bean
//        public InstantiationAwareBeanPostProcessor init() {
//            return new InstantiationAwareBeanPostProcessor() {
//                @Override
//                public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//                    if(beanClass.equals(Config1.class)){
//
//                        logger.info(beanName + "::execute =====> postProcessBeforeInstantiation");
//                        return beanFactory.getBean(beanName);
//                    }
//                    return null;
//                }
//
//                @Override
//                public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
//                    logger.info(beanName + "::execute =====> postProcessAfterInstantiation");
//                    return true;
//                }
//
//            };
//        }

        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }
    }

    @Configuration
    public static class Config3 implements Sout {

        @Bean
        public Cat cat() {
            return new Cat();
        }


        @Override
        public void sout() {
            cat();
        }

        @Override
        public void sout2() {

        }
    }

    public static class Cat implements Sout {


        public static volatile int times;

        public Cat() {
            sout();
        }


        @Override
        public void sout() {
            System.out.println(times++);
        }

        @Override
        public void sout2() {

        }
    }


}
